package org.gw.building.ctrl;

import com.alibaba.fastjson.JSONArray;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.gw.building.model.ClassInfo;
import org.gw.building.model.StuInfo;
import org.gw.building.model.Term;
import org.gw.building.repositories.ClassInfoRepository;
import org.gw.building.repositories.StuInfoRepository;
import org.gw.building.repositories.TermRepository;
import org.gw.building.util.FileHelper;
import org.gw.ylc.base.context.RequestContextHolder;
import org.gw.ylc.base.interceptor.RequestPermission;
import org.gw.ylc.base.model.Student;
import org.gw.ylc.base.repositories.StudentRepository;
import org.gw.ylc.base.repositories.UserInfoRepository;
import org.gw.ylc.base.util.PermissionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * 学员管理
 * 
 * @author babyv
 *
 */
@Controller
@RequestMapping("trainee")
public class TraineeCtrl {
	@Autowired
	private StuInfoRepository stuInfoRepository;
	@Autowired
	private ClassInfoRepository classInfoRepository;
	@Autowired
	private StudentRepository studentRepository;
	@Autowired
	private TermRepository termRepository;
	@Autowired
	private UserInfoRepository userInfoRepository;

	/**
	 * 查找当前期次的学员
	 * 
	 * @param term
	 * @param name
	 * @param grade
	 * @param department
	 * @param clazz
	 * @param sfsqtzs
	 * @param sftzs
	 * @return
	 */
	@RequestMapping("queryStudents")
	@ResponseBody
	public Page<StuInfo> queryStudents(String term, String name, String grade, String department, String clazz,
			Integer sfsqtzs, Integer sftzs, Integer status, String xq) {
		return stuInfoRepository.queryStudents(term, PermissionUtil.toLikeString(name), grade, department, clazz,
				sfsqtzs, sftzs, status, xq, RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("queryDispatchStudents")
	@ResponseBody
	public Page<StuInfo> queryDispatchStudents(String term) {
		return stuInfoRepository.queryDispatchStudents(term, RequestContextHolder.get().getPageRequest());
	}

	@RequestMapping("getDispatchInfo")
	@ResponseBody
	public Object getDispatchInfo(String id) {
		Map<String, Object> r = new HashMap<String, Object>();
		Term currentTerm = termRepository.findOne(id);
		r.put("currentTerm", currentTerm);
		if (currentTerm != null) {
			List<ClassInfo> classInfoList = classInfoRepository.getAllByTerm(currentTerm.getId());
			r.put("classInfoList", classInfoList);
			long allStudentCount = stuInfoRepository.countByTerm(currentTerm.getId());
			r.put("allStudentCount", allStudentCount);
			long dispatchedCount = stuInfoRepository.countDispatchedByTerm(currentTerm.getId());
			r.put("dispatchedCount", dispatchedCount);
			List<Object[]> allByTerm = stuInfoRepository.getAllByTerm(currentTerm.getId());
			r.put("students", allByTerm);
		}
		return r;
	}

	@RequestMapping("getClassInfoList")
	@ResponseBody
	public Object getClassInfoList(String term) {
		List<ClassInfo> classInfoList = classInfoRepository.getAllByTerm(term);
		return classInfoList;
	}

	/**
	 * 添加学员
	 * 
	 * @param stuInfo
	 * @return
	 */
	@RequestMapping("add")
	@ResponseBody
	public Object addStudent(StuInfo stuInfo) {
		if (stuInfo.getStatus() == null) {
			stuInfo.setStatus(0);
		}
		stuInfoRepository.save(stuInfo);
		return "success";
	}

	@RequestMapping("updateMyInfo")
	@ResponseBody
	@RequestPermission(RequestPermission.STUDENT)
	public Object updateMyInfo(StuInfo stuInfo) {
		StuInfo findOneByXh = stuInfoRepository.findByXh(RequestContextHolder.get().getUser().getUid()).get(0);
		findOneByXh.setLxfs(stuInfo.getLxfs());
		findOneByXh.setXq(stuInfo.getXq());
		return stuInfoRepository.save(findOneByXh);
	}

	@RequestMapping("getByXh")
	@ResponseBody
	public Object getByXh(String xh) {
		return stuInfoRepository.findByXh(xh).stream().findFirst().orElse(null);
	}

	@RequestMapping("findAllByIds")
	@ResponseBody
	public Object findAllByIds(String[] ids) {
		return stuInfoRepository.findAll(Arrays.asList(ids));
	}

	@RequestMapping("getRawStudent")
	@ResponseBody
	public Object getRawStudent() {
		return studentRepository.findByXh(RequestContextHolder.get().getUser().getUid());
	}

	@RequestMapping("queryRawStudent")
	@ResponseBody
	public Object queryRawStudent(String name) {
		return studentRepository.queryStudent(PermissionUtil.toLikeString(name), null, null, null, null, null, null,
				null, null, null, null, null, null, RequestContextHolder.get().getPageRequest());
	}

	/**
	 * 分班管理
	 * 
	 * @param rule
	 *            规则
	 * @param memberSize
	 *            班级人数限制
	 * @return
	 */
	@RequestMapping("dispatch")
	@ResponseBody
	public Object dispatch(StudentDispatchForm dispatchForm) {
		JSONArray students = dispatchForm.getStudentsArray();
		String claaName = dispatchForm.getClaaName();
		Integer memberSize = dispatchForm.getMemberSize();
		if (claaName == null) {
			claaName = "";
		}
		for (int i = 0; i < students.size(); i++) {
			ClassInfo classInfo = classInfoRepository.getBybjCodeAndTerm(String.valueOf(i + 1), dispatchForm.getTerm());
			if (classInfo == null) {
				classInfo = new ClassInfo();
				classInfo.setBjCode((i + 1) + "");
				classInfo.setTerm(dispatchForm.getTerm());
			}
			JSONArray array = students.getJSONArray(i);
			List<String> ids = new ArrayList<String>();
			for (int j = 0; j < array.size(); j++) {
				JSONArray s = array.getJSONArray(j);
				String id = s.getString(0);
				ids.add(id);
			}
			classInfo.setBjName(claaName + classInfo.getBjCode() + "班");
			classInfo.setFbbzrs(memberSize);
			classInfo.setBjrs(ids.size());
			classInfo = classInfoRepository.save(classInfo);
			stuInfoRepository.updateClassInIds(ids, classInfo);
		}
		classInfoRepository.deleteBybjCodeGreaterThanAndTerm("" + students.size(), dispatchForm.getTerm());
		return "succ";
	}

	/**
	 * 导入学员
	 * 
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("importStu")
	@ResponseBody
	public Object importStu(MultipartFile file, String term) throws Exception {
		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + file.getOriginalFilename();
		File xlsFile = new File(xlsFilePath);
		FileUtils.copyInputStreamToFile(file.getInputStream(), xlsFile);
		return doImportStu(xlsFile, term);
	}

	private final static List<String> STU_IMP_HEADERS = Arrays
			.asList(new String[] { "学号", "校区", "联系电话", "所属班级", "是否为团支书", "备注" });

	private String doImportStu(File xlsFile, String term) throws BiffException, IOException {
		Workbook workbook = Workbook.getWorkbook(xlsFile);
		Sheet sheet = workbook.getSheet(0);
		int rows = sheet.getRows();
		int columns = sheet.getColumns();
		/** Main content */
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		/** Headers */
		// [学号、校区、联系电话、所属班级、是否为团支书、备注]
		List<String> headers = new ArrayList<String>();
		for (int row = 0; row < rows; row++) {
			Map<String, String> map = new LinkedHashMap<String, String>();
			for (int col = 0; col < columns; col++) {
				String s = sheet.getCell(col, row).getContents();
				if (row == 0) {
					headers.add(s != null ? s.trim().toLowerCase() : "");
				} else {
					map.put(headers.get(col), s != null ? s.trim() : "");
				}
			}
			if (row != 0)
				list.add(map);
		}
		// 校验header
		if (!ArrayUtils.isEquals(headers, STU_IMP_HEADERS)) {
			return "导入的文件中的表头不正确，应该是：" + STU_IMP_HEADERS;
		}
		// 逐行处理数据
		StringBuffer message = new StringBuffer();
		final List<StuInfo> allList = new ArrayList<StuInfo>();
		for (Map<String, String> row : list) {
			String xh = row.get("学号");
			String xq = row.get("校区");
			String lxdh = row.get("联系电话");
			String ssbj = row.get("所属班级");
			String sftzs = row.get("是否为团支书");
			String bz = row.get("备注");
			StuInfo stu = stuInfoRepository.findOneByXhAndTerm(xh, term);
			Term termObj = new Term();
			termObj.setId(term);
			if (stu == null) {
				stu = new StuInfo();
				Student s = studentRepository.findByXh(xh);
				if (s == null) {
					message.append("学生" + xh + "不存在\n");
					continue;
				}
				stu.setUser(userInfoRepository.findOne(s.getId()));
				stu.setTerm(termObj);
			}
			ClassInfo c = classInfoRepository.getBybjNameAndTerm(ssbj, termObj);
			if (c == null) {
				message.append("所属班级" + ssbj + "不存在\n");
				continue;
			}
			stu.setClassInfo(c);
			stu.setXq(xq);
			stu.setLxfs(lxdh);
			stu.setSfwtzs("是".equals(sftzs) ? 1 : 0);
			stu.setBz(bz);
			stu.setStatus(0);
			allList.add(stu);
		}
		if (allList.size() > 0) {
			stuInfoRepository.save(new Iterable<StuInfo>() {
				@Override
				public Iterator<StuInfo> iterator() {
					return allList.iterator();
				}
			});
		}
		return message.toString();
	}

	/**
	 * 导出学员/学员中的团支书
	 * 
	 * @return
	 * @throws IOException
	 * @throws FileNotFoundException
	 * @throws WriteException
	 * @throws RowsExceededException
	 */
	@RequestMapping("exportStu")
	@ResponseBody
	public Object exportStu(String term, String name, String grade, String department, String clazz, Integer sfsqtzs,
			Integer sftzs, Integer status, String xq, HttpServletResponse response)
			throws FileNotFoundException, IOException, RowsExceededException, WriteException {
		Page<StuInfo> stus = stuInfoRepository.queryStudents(term, PermissionUtil.toLikeString(name), grade, department,
				clazz, sfsqtzs, sftzs, status, xq, new PageRequest(0, Integer.MAX_VALUE));
		File tempFolder = FileHelper.getTempFolder("train_");
		String xlsFileName = "学员信息.xls";
		String xlsFilePath = tempFolder.getAbsolutePath() + "/" + xlsFileName;
		File xlsFile = new File(xlsFilePath);
		response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(xlsFileName, "UTF-8"));
		response.setContentType("application/octet-stream;charset=UTF-8");
		doExport(xlsFile, stus.getContent());
		OutputStream out = response.getOutputStream();
		FileCopyUtils.copy(new FileInputStream(xlsFile), out);
		out.flush();
		return null;
	}

	private void doExport(File xlsFile, List<StuInfo> stus) throws IOException, RowsExceededException, WriteException {
		WritableWorkbook book = null;
		String[] headers = { "姓名", "性别", "学号", "年级", "院系", "所属班级", "学生类别", "联系电话", "校区", "是否为团支书" };
		try {
			book = Workbook.createWorkbook(xlsFile);
			WritableSheet sheet = book.createSheet("学员信息", 0);
			/** 写header */
			for (int i = 0; i < headers.length; i++) {
				sheet.addCell(new Label(i, 0, headers[i]));
			}
			int row = 1;
			for (StuInfo stu : stus) {
				sheet.addCell(new Label(0, row, stu.getUser().getName()));
				sheet.addCell(new Label(1, row, stu.getSexString()));
				sheet.addCell(new Label(2, row, stu.getUser().getUid()));
				sheet.addCell(new Label(3, row, stu.getUser().getGrade()));
				sheet.addCell(new Label(4, row, stu.getUser().getDepartment()));
				sheet.addCell(new Label(5, row, stu.getClassInfo() == null ? "" : stu.getClassInfo().getBjName()));
				sheet.addCell(new Label(6, row, ""));// TODO: 学生类别
				sheet.addCell(new Label(7, row, stu.getLxfs()));
				sheet.addCell(new Label(8, row, stu.getXq()));
				sheet.addCell(new Label(9, row, stu.getSfwtzs() == 1 ? "是" : "否"));
				row += 1;
			}
			book.write();
		} finally {
			if (book != null)
				try {
					book.close();
				} catch (WriteException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
}
